package cn.tristenstudy.blog.config;

import cn.tristenstudy.blog.pojo.User;
import cn.tristenstudy.blog.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;

/**
 * 自定义的Realm
 *
 * @author xichen1.li
 * @date 2020-10-29 19:27
 */
public class UserRealm extends AuthorizingRealm {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    UserService userService;

    /**
     * 授权
     *
     * @param principalCollection  principalCollection
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        logger.info("授权=>doGetAuthorizationInfo()");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //拿到当前登录的对象
        Subject subject = SecurityUtils.getSubject();
        User currentUser = (User) subject.getPrincipal();
        //设置用户权限
        info.addStringPermission(currentUser.getType());

        return info;
    }

    /**
     * 认证
     *
     * @param token token
     * @return 结果
     * @throws AuthenticationException 认证不通过
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        logger.info("认证=>doGetAuthenticationInfo()");
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        //获取用户
        String username = userToken.getUsername();
        User user = userService.queryUserByName(username);
        if (ObjectUtils.isEmpty(user)) {
            //抛出 UnknownAccountException异常
            return null;
        }
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        session.setAttribute("user", user);
        //通过SimpleAuthenticationInfo做身份处理,密码认证shiro内部做
        return new SimpleAuthenticationInfo(user,user.getPassword(), ByteSource.Util.bytes(user.getSalt()),getName());
    }
}
